package org.poindextrose.ant;

import java.io.File;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.selectors.BaseSelector;

public class RangeSelector extends BaseSelector {
    
    private int from = -1;
    private int to = -1;
    
    /**
     * @param rangeVal
     * @return
     * @throws Exception
     */
    protected int setRangeValue(String rangeVal) throws Exception {
        int result = -1;
        if ((rangeVal != null) && !(rangeVal.equals("")) && !(rangeVal.equals("*"))) {
            int tempVal = 0;
            try {
                tempVal = new Integer(rangeVal).intValue();
            } catch (NumberFormatException e) {
                throw new Exception("needs to be a positive integer or '*'");
            }
            if (tempVal < 0) {
                throw new Exception("needs to be a positive integer or '*'");
            }
            result = tempVal;
        }
        return result;
    }
    
    /**
     * @param from
     */
    public void setFrom(String from) {
        try {
            this.from = setRangeValue(from);
        } catch (Exception e) {
            throw new BuildException("'from' "+e.getMessage());
        }
    }

    /**
     * @param to
     */
    public void setTo(String to) {
        try {
            this.to = setRangeValue(to);
        } catch (Exception e) {
            throw new BuildException("'to' "+e.getMessage());
        }
    }

    /* (non-Javadoc)
     * @see org.apache.tools.ant.types.selectors.BaseSelector#isSelected(java.io.File, java.lang.String, java.io.File)
     */
    public boolean isSelected(File basedir, String filename, File file) {
        validate();
        
        // Get the integer off the front of the filename
        Integer prefixFromString = prefixFromString(filename);
        if (prefixFromString == null) {
            // this filename has no version so we skip it!
            return false;
        }
        
        return versionWithinBounds(prefixFromString.intValue(), this.from, this.to);   
    }
    
    /**
     * @param version
     * @param lower
     * @param upper
     * @return
     */
    private boolean versionWithinBounds(int version, int lower, int upper) {
        if (version < 0) {
            // we are not supporting versions with negative numbers, skip it!
            return false;
        }
        
        // if file version is less than our lower bound, dump it!
        if (version < lower) {
            return false;
        }
        
        // if file version is higher than the upper bound, dump it!
        if ((version > upper) && (upper != -1)) {
            return false;
        }        
        
        return true;        
    }
    
    /**
     * @param str
     * @return
     */
    protected Integer prefixFromString(String str) {
        if (str == null) {
            return null;
        }
        String prefixStr = str.split("_", 2)[0];
        Integer prefix = null;
        try {
            prefix = new Integer(prefixStr);
        } catch (NumberFormatException e) {
            prefix = null;
        }
        return prefix;
    }

    /* (non-Javadoc)
     * @see org.apache.tools.ant.types.selectors.BaseSelector#verifySettings()
     */
    public void verifySettings() {
        super.verifySettings();
        if (from < -1) {
            throw new BuildException("From needs to be a positive integer or '*'");
        } else if (to < -1) {
            throw new BuildException("To needs to be a positive integer or '*'");
        } else if ((to > -1) && (from > -1)) {
            if (to < from) {
                throw new BuildException("From needs to be less than or equal to To");
            }
        }
    }    
}
